//服务器
var bearcat = require("bearcat")
var uuid = require("uuid")
const build_list = require("../../config/build_list.json")
const build_type = require("../../config/build_type.json")
const grids = require("../../config/grids.json")
const async = require("async")
var build_back_map = {}
var build_front_map = {}
for(var i in build_type){
	build_back_map[build_type[i]["build_1"]] = build_type[i]["build_2"]
	build_back_map[build_type[i]["build_2"]] = build_type[i]["build_3"]
	build_front_map[build_type[i]["build_2"]] = build_type[i]["build_1"]
	build_front_map[build_type[i]["build_3"]] = build_type[i]["build_2"]
}
var area = function(app) {
	this.app = app
	this.channelService = this.app.get('channelService')
}
//服务器初始化
area.prototype.init = function() {
	console.log("area 初始化")
}
//解锁地块
area.prototype.unlockGrid = function(uid,gridId,cb) {
	if(!grids[gridId]){
		cb(false,"参数错误"+gridId)
		return
	}
	var self = this
	var arr = ["gridNumber","gold","grid_build_"+gridId]
	self.redisDao.db.hmget("playerInfo:user:"+uid,arr,function(err,list) {
		var gridNumber = Number(list[0])
		var gold = Number(list[1])
		var grid = Number(list[2])
		var needGold = grids[gridNumber + 1]["value"]
		if(gridNumber >= 9 || !grids[gridNumber + 1]){
			cb(false,"已全部解锁")
			return
		}
		if(grid){
			cb(false,"地块已解锁")
			return
		}
		if(gold < needGold){
			cb(false,"金币不足")
			return
		}
		self.redisDao.db.hset("playerInfo:user:"+uid,"grid_build_"+gridId,1)
		self.redisDao.db.hincrby("playerInfo:user:"+uid,"gridNumber",1)
		self.goldChange(uid,-needGold)
		self.assetsChange(uid,needGold)
		cb(true)
	})
}
//解锁建筑
area.prototype.unlockBuild = function(uid,buildId,cb) {
	if(!build_list[buildId]){
		cb(false,"参数错误"+buildId)
		return
	}
	var self = this
	var arr = ["build_"+buildId,"gold"]
	self.redisDao.db.hmget("playerInfo:user:"+uid,arr,function(err,list) {
		var build = Number(list[0])
		var gold = Number(list[1])
		if(build){
			cb(false,"建筑已解锁")
			return
		}
		if(gold < build_list[buildId]["unlock"]){
			cb(false,"金币不足")
			return
		}
		self.redisDao.db.hset("playerInfo:user:"+uid,"build_"+buildId,1)
		self.goldChange(uid,-build_list[buildId]["unlock"])
		self.assetsChange(uid,build_list[buildId]["unlock"])
		cb(true)
	})
}
//放置建筑
area.prototype.placeBuild = function(uid,gridId,buildId,cb) {
	if(!grids[gridId] || !build_list[buildId]){
		cb(false,"参数错误")
		return
	}
	var self = this
	var lv,oldGridId
	async.waterfall([
		function(next) {
			var arr = ["build_"+buildId,"grid_build_"+gridId,"map_build_"+buildId]
			self.redisDao.db.hmget("playerInfo:user:"+uid,arr,function(err,list) {
				lv = Number(list[0])
				oldGridId = Number(list[1])
				if(list[2]){
					next("该建筑已放置")
					return
				}
				if(!oldGridId){
					next("地块未解锁")
					return
				}
				if(!lv){
					next("建筑未解锁")
					return
				}
				next()
			})
		},
		function(next) {
			//保存前置建筑收益
			if(build_front_map[oldGridId]){
				self.saveBuildAward(uid,build_front_map[oldGridId],function() {
					if(build_front_map[buildId]){
						self.saveBuildAward(uid,build_front_map[buildId],function() {
							next()
						})
					}else{
						next()
					}
				})
			}else{
				next()
			}
		},
		function(next) {
			//提取收益
			if(oldGridId && oldGridId != 1){
				self.gainBuildAward(uid,gridId,function() {
					self.redisDao.db.hdel("playerInfo:user:"+uid,"map_build_"+oldGridId)
					next()
				})
			}else{
				next()
			}
		},
		function(next) {
			self.redisDao.db.hset("playerInfo:user:"+uid,"grid_build_"+gridId,buildId)
			self.redisDao.db.hset("playerInfo:user:"+uid,"grid_time_"+gridId,Date.now())
			self.redisDao.db.hset("playerInfo:user:"+uid,"grid_award_"+gridId,0)
			self.redisDao.db.hset("playerInfo:user:"+uid,"map_build_"+buildId,gridId)
			cb(true)
		}
	],function(err) {
		cb(false,err)
	})
}
//更新收益
area.prototype.updateBuildAward = function(buildId,lv,time,award,add) {
	var build = build_list[buildId]
	var earning = Math.floor(build_list[buildId]["earning_"+lv] * (1+add))
	var curTime = Date.now()
	var total = Math.floor(earning * (curTime - time) / 1000  + award)
	var max = Math.floor(earning * 28800000)
	if(total > max){
		total = max
	}
	return {award:total,time:curTime}
}
//保存建筑当前收益
area.prototype.saveBuildAward = function(uid,buildId,cb) {
	var self = this
	self.redisDao.db.hget("playerInfo:user:"+uid,"map_build_"+buildId,function(err,gridId) {
		if(gridId){
			var arr = ["grid_build_"+gridId,"grid_time_"+gridId,"grid_award_"+gridId]
			self.redisDao.db.hmget("playerInfo:user:"+uid,arr,function(err,list) {
				var buildId = Number(list[0])
				var time = Number(list[1])
				var award = Number(list[2])
				if(!buildId || !build_list[buildId]){
					cb(false,"该地块无建筑")
					return
				}
				arr = ["build_"+buildId,"map_build_"+build_back_map[buildId]]
				self.redisDao.db.hmget("playerInfo:user:"+uid,arr,function(err,list) {
					var lv = Number(list[0])
					var add = list[1] ? 0.5:0
					var info = self.updateBuildAward(buildId,lv,time,award,add)
					self.redisDao.db.hset("playerInfo:user:"+uid,"grid_time_"+gridId,info.time)
					self.redisDao.db.hset("playerInfo:user:"+uid,"grid_award_"+gridId,info.award)
					var notify = {
						type : "build_award_change",
						buildId : buildId,
						gridId : gridId,
						award : info.award,
						time : info.time
					}
					self.sendToUser(uid,notify)
					cb(true)
				})
			})
		}else{
			cb()
		}
	})
}
//升级建筑
area.prototype.upgradeBuild = function(uid,buildId,cb) {
	if(!build_list[buildId]){
		cb(false,"参数错误")
		return
	}
	var self = this
	var arr = ["build_"+buildId,"gold","map_build_"+buildId]
	self.redisDao.db.hmget("playerInfo:user:"+uid,arr,function(err,list) {
		var lv = Number(list[0])
		var gold = Number(list[1])
		var grid = list[2]
		if(!lv){
			cb(false,"建筑未解锁")
			return
		}
		if(!build_list[buildId]["upgrade_"+(lv+1)]){
			cb(false,"已满级")
			return
		}
		var needGold = build_list[buildId]["upgrade_"+lv]
		if(gold < needGold){
			cb(false,"金币不足")
			return
		}
		if(grid){
			self.gainBuildAward(uid,grid,function() {
				self.redisDao.db.hincrby("playerInfo:user:"+uid,"build_"+buildId,1)
				self.goldChange(uid,-needGold)
				self.assetsChange(uid,needGold)
				cb(true)
			})
		}else{
			self.redisDao.db.hincrby("playerInfo:user:"+uid,"build_"+buildId,1)
			self.goldChange(uid,-needGold)
			self.assetsChange(uid,needGold)
			cb(true)
		}
	})
}
//提取收益
area.prototype.gainBuildAward = function(uid,gridId,cb) {
	if(!grids[gridId]){
		cb(false,"参数错误")
		return
	}
	var self = this
	var arr = ["grid_build_"+gridId,"grid_time_"+gridId,"grid_award_"+gridId]
	self.redisDao.db.hmget("playerInfo:user:"+uid,arr,function(err,list) {
		var buildId = Number(list[0])
		var time = Number(list[1])
		var award = Number(list[2])
		if(!buildId || !build_list[buildId]){
			cb(false,"该地块无建筑")
			return
		}
		arr = ["build_"+buildId,"map_build_"+build_back_map[buildId]]
		self.redisDao.db.hmget("playerInfo:user:"+uid,arr,function(err,list) {
			var lv = Number(list[0])
			var add = list[1] ? 0.5:0
			var info = self.updateBuildAward(buildId,lv,time,award,add)
			self.goldChange(uid,info.award)
			self.redisDao.db.hset("playerInfo:user:"+uid,"grid_time_"+gridId,info.time)
			self.redisDao.db.hset("playerInfo:user:"+uid,"grid_award_"+gridId,0)
			cb(true,info)
		})
	})
}
//金币改变
area.prototype.goldChange = function(uid,value) {
	if(!value)
		return
	var self = this
	self.redisDao.db.hincrby("playerInfo:user:"+uid,"gold",value,function(err,data) {
		var notify = {
			type : "goldChange",
			value : value,
			curValue : Number(data)
		}
		self.sendToUser(uid,notify)
	})
}
//总资产改变
area.prototype.assetsChange = function(uid,value) {
	if(!value)
		return
	var self = this
	self.redisDao.db.hincrby("playerInfo:user:"+uid,"assets",value,function(err,data) {
		var notify = {
			type : "assetsChange",
			value : value,
			curValue : Number(data)
		}
		self.redisDao.db.zadd("assetsRank",notify.curValue,uid)
		self.sendToUser(uid,notify)
	})
}
//获取排行榜
area.prototype.getAssetsRank = function(uid,cb) {
	var self = this
	self.redisDao.db.zrevrange("assetsRank",0,19,"WITHSCORES",function(err,list) {
		var uids = []
		var scores = []
		for(var i = 0;i < list.length;i += 2){
			uids.push(list[i])
			scores.push(list[i+1])
		}
		self.getPlayerInfoByUids(uids,function(userInfos) {
			var info = {}
			info.userInfos = userInfos
			info.scores = scores
			cb(true,info)
		})
	})
}
//领取填字游戏奖励
area.prototype.gainCrosswordAward = function(uid,cb) {
	var self = this
	self.redisDao.db.hincrby("playerInfo:user:"+uid,"crossword_num",1,function(err,num) {
		var info = {}
		info.num = Number(num)
		info.award = info.num * 10000
		self.goldChange(uid,info.award)
		cb(true,info)
	})
}
//获取船只货物
area.prototype.getShipCargo = function(uid,cb) {
	var self = this
	var arr = ["ship_time"]
	for(var i = 1;i <= 9;i++)
		arr.push("grid_build_"+i)
	self.redisDao.db.hmget("playerInfo:user:"+uid,arr,function(err,data) {
		var curTime = Date.now()
		var time = Number(data[0])
		if(false && curTime < time + 110000){
			cb(false,"需间隔2分钟")
		}else{
			var info = {ship_time : curTime}
			var list = []
			for(var i = 1;i <= 9;i++){
				if(data[i] && build_list[data[i]]){
					list.push(Number(data[i]))
				}
			}
			if(!list.length){
				cb(false,"无可用货物")
				return
			}
			var num = Math.random() < 0.6 ? 3:2
			for(var i = 1;i <= 3;i++){
				if(i <= num){
					info["ship_build_"+i] = list[Math.floor(Math.random() * list.length)]
					info["ship_count_"+i] = Math.floor(Math.random() * 3) + 1
				}else{
					info["ship_build_"+i] = 0
					info["ship_count_"+i] = 0
				}
			}
			self.redisDao.db.hmset("playerInfo:user:"+uid,info)
			cb(true,info)
		}
	})
}
//领取船只货物奖励
area.prototype.gainShipAward = function(uid,shipId,cb) {
	if(shipId != 1 && shipId != 2 && shipId != 3){
		cb(false,"shipId error"+shipId)
		return
	}
	var self = this
	var arr = ["ship_build_"+shipId,"ship_count_"+shipId]
	self.redisDao.db.hmget("playerInfo:user:"+uid,arr,function(err,list) {
		var buildId = Number(list[0])
		var count = Number(list[1])
		if(!buildId || count <= 0){
			cb(false,"船只货物不存在")
			return
		}
		arr = ["build_"+buildId]
		self.redisDao.db.hmget("playerInfo:user:"+uid,arr,function(err,list) {
			var lv = Number(list[0])
			var info = self.updateBuildAward(buildId,lv,Date.now()-60000,0,0)
			self.redisDao.db.hincrby("playerInfo:user:"+uid,"ship_count_"+shipId,-1,function(err,data) {
				if(data >= 0){
					self.goldChange(uid,info.award)
					cb(true,info.award)
				}else{
					cb(false,"船只货物不存在")
				}
			})
		})
	})
}
//批量获取玩家基本数据
area.prototype.getPlayerInfoByUids = function(uids,cb) {
	var self = this
	var multiList = []
	for(var i = 0;i < uids.length;i++){
		multiList.push(["hmget","acc:user:"+uids[i],["name","head"]])
	}
	self.redisDao.multi(multiList,function(err,list) {
		var userInfos = []
		for(var i = 0;i < uids.length;i++){
			var info = {
				uid : uids[i],
				name : list[i][0],
				head : list[i][1]
			}
			userInfos.push(info)
		}
		cb(userInfos)
	})
}
//发送消息给玩家
area.prototype.sendToUser = function(uid,notify) {
	this.channelService.pushMessageByUids('onMessage', notify, [{
      uid: uid,
      sid: "connector-server-1"
    }])
}
module.exports = {
	id : "area",
	func : area,
	init : "init",
	lazy : true,
	args : [{
		name : "app",
		type : "Object"
	}],
	props : [{
		name : "redisDao",
		ref : "redisDao"
	}]
}